﻿using System.Text;
using Gateway.IQuery;
using Gateway.IQuery.Question;
using Gateway.IQuery.Question.Request;
using Gateway.IQuery.Question.Result;
using Gateway.IRepositories;
using Gateway.SqlSugar;

namespace Gateway.Query;

/// <summary>
/// 
/// </summary>
public class QuestionQuery : IQuestionQuery
{
    private readonly IQueryRepository _repository;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="repository"></param>
    public QuestionQuery(IQueryRepository repository)
    {
        _repository = repository;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<PageResult<QuestionListResult>> GetPageList(QuestionPageListRequest request)
    {
        StringBuilder where = new StringBuilder(100);
        SugarParameters parameters = new SugarParameters();
        if (!string.IsNullOrEmpty(request.QuestionName))
        {
            where.Append(" AND  q.QuestionName like @QuestionName");
            parameters.Add("@QuestionName", $"%{request.QuestionName}%");
        }

        int count = 0;
        if (request.Page == 1)
        {
            count = await _repository.QueryFirstOrDefaultAsync<int>(
                $@"select count(1) from  Question q where Deleted='N' {where.ToString()}", parameters);
        }

        string sql =
            $@"select q.QuestionId,q.QuestionName,q.Disabled,q.CreatedTime,q.QuestionDescribe from  Question q where q.Deleted='N'
{where.ToString()}
order by  q.QuestionId,q.CreatedTime
limit  {request.Offset},{request.PageSize}";
        var data = await _repository.QueryAsync<QuestionListResult>(sql, parameters);
        return PageResult<QuestionListResult>.Create(data.ToList(), count);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<QuestionDetailResult> GetDetail(string id)
    {
        var question = await _repository.QueryFirstOrDefaultAsync<QuestionDetailResult>(
            "select q.QuestionId, q.QuestionName, q.QuestionDescribe, q.QuestionCase, q.CreatedBy, q.CreatorName, q.CreatedTime, q.LastModifiedBy, q.LastModifierName, q.LastModifiedTime, q.Disabled from  Question q where  q.Deleted='N' and q.QuestionId=@id",
            new { id });
        if (question != null)
        {
            var languages = await _repository.QueryListAsync<QuestionLanguageDetailResult>(
                @"select q.*,l.Text as langText from  QuestionLanguage q
left join Language l  on q.Language=l.Lang and l.Deleted='N'
where q.QuestionId=@id", new { id });
            if (languages.Count > 0)
            {
                var questionExtensionCodes =
                    await _repository.QueryListAsync<QuestionExtensionCodeDetailResult>(
                        @"select * from  QuestionExtensionCode p where p.QuestionId=@id", new { id });
                if (questionExtensionCodes.Count > 0)
                {
                    foreach (var item in languages)
                    {
                        var codes = questionExtensionCodes.Where(p =>
                            p.QuestionLanguageId.Equals(item.QuestionLanguageId));
                        item.ExtensionCodes = codes.ToList();
                    }
                }
            }

            question.Languages = languages;
        }

        return question;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="id"></param>
    /// <param name="lang"></param>
    /// <returns></returns>
    public async Task<QuestionDetailResult> GetDetail(string id, string lang)
    {
        var question = await _repository.QueryFirstOrDefaultAsync<QuestionDetailResult>(
            "select q.QuestionId, q.QuestionName, q.QuestionDescribe, q.QuestionCase, q.CreatedBy, q.CreatorName, q.CreatedTime, q.LastModifiedBy, q.LastModifierName, q.LastModifiedTime, q.Disabled from  Question q where  q.Deleted='N' and q.QuestionId=@id",
            new { id });
        if (question != null)
        {
            var languages = await _repository.QueryListAsync<QuestionLanguageDetailResult>(
                @"select q.*,l.Text as langText from  QuestionLanguage q
left join Language l  on q.Language=l.Lang and l.Deleted='N'
where q.QuestionId=@id and q.language=@lang", new { id, lang });
            if (languages.Count > 0)
            {
                var questionExtensionCodes =
                    await _repository.QueryListAsync<QuestionExtensionCodeDetailResult>(
                        @"select * from  QuestionExtensionCode p where p.QuestionId=@id", new { id });
                if (questionExtensionCodes.Count > 0)
                {
                    foreach (var item in languages)
                    {
                        var codes = questionExtensionCodes.Where(p =>
                            p.QuestionLanguageId.Equals(item.QuestionLanguageId));
                        item.ExtensionCodes = codes.ToList();
                    }
                }
            }

            question.Languages = languages;
        }

        return question;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<QuestionDetailResult> GetSimpleDetail(string id)
    {
        var question = await _repository.QueryFirstOrDefaultAsync<QuestionDetailResult>(
            "select q.QuestionId, q.QuestionName, q.QuestionDescribe, q.QuestionCase, q.CreatedBy, q.CreatorName, q.CreatedTime, q.LastModifiedBy, q.LastModifierName, q.LastModifiedTime, q.Disabled from  Question q where  q.Deleted='N' and q.QuestionId=@id",
            new { id });
        return question;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public async Task<List<QuestionListResult>> GetAllList()
    {
        var question = await _repository.QueryListAsync<QuestionListResult>(
            "select q.QuestionId, q.QuestionName, q.QuestionDescribe, q.QuestionCase, q.CreatedBy, q.CreatedTime, q.LastModifiedTime from  Question q where  q.Deleted='N' and Disabled='N' ");
        return question;
    }
}